package com.defysoft.waukids.slide;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;

import org.json.JSONObject;

import android.app.Activity;
import android.bluetooth.BluetoothAdapter;
import android.bluetooth.BluetoothDevice;
import android.bluetooth.BluetoothGattCharacteristic;
import android.bluetooth.BluetoothGattService;
import android.bluetooth.BluetoothManager;
import android.content.BroadcastReceiver;
import android.content.ComponentName;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.content.ServiceConnection;
import android.os.Bundle;
import android.os.Handler;
import android.os.IBinder;
import android.os.Message;
import android.support.v7.widget.Toolbar;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.TextView;
import android.widget.Toast;

import com.defysoft.waukids.BaseActivity;
import com.defysoft.waukids.BluetoothLeService;
import com.defysoft.waukids.Data_Sharedpreferences;
import com.defysoft.waukids.PublicSharedpreferences;
import com.defysoft.waukids.R;
import com.defysoft.waukids.SampleGattAttributes;
import com.defysoft.waukids.Sqlite_Connect;

public class Main_Slide_Beacon extends BaseActivity {
	Toolbar toolbar;
	TextView state;
	TextView start;
	private BluetoothAdapter mBluetoothAdapter;
	private static final int REQUEST_ENABLE_BT = 3;
	private long SCAN_PERIOD = 5000;
	private Handler mHandler;
	int stu = 0;
	String beacon = "";
	boolean check = false;
	private BluetoothGattCharacteristic mNotifyCharacteristic;
	private final String LIST_NAME = "NAME";
	private final String LIST_UUID = "UUID";
	private ArrayList<ArrayList<BluetoothGattCharacteristic>> mGattCharacteristics = new ArrayList<ArrayList<BluetoothGattCharacteristic>>();
	final int SUCCESS = 10;
	final int FAIR = 9;
	final int SCANSUCCESS = 8;
	final int SCANFAIR = 7;
	final int BATTERYUP = 6;
	String battery;
	BluetoothLeService mBluetoothLeService;
	public Sqlite_Connect sqlite_Connect;
	PublicSharedpreferences psf;
	Data_Sharedpreferences.SF_Member member;
	public void onActivityResult(int requestCode, int resultCode, Intent data) {// ���������������üũ

		switch (requestCode) {
		case REQUEST_ENABLE_BT:
			// When the request to enable Bluetooth returns
			if (resultCode == Activity.RESULT_OK) { // ������� ������
				// Bluetooth is now enabled, so set up a chat session
				Toast.makeText(this, "블루투스 사용가능", Toast.LENGTH_LONG).show();
				check = false;
				scanLeDevice(true);
				startDIal();
			} else { // ������� ������ ���� �����佺Ʈ ���� ��
				// User did not enable Bluetooth or an error occurred
				Toast.makeText(this, "블루투스 사용불가", Toast.LENGTH_LONG).show();
				finish();
			}
		}
	}

	@Override
	protected void onCreate(Bundle arg0) {
		// TODO Auto-generated method stub
		super.onCreate(arg0);
		sqlite_Connect = new Sqlite_Connect(this);
		setContentView(R.layout.main_slide_beacon_activity);
		psf = new PublicSharedpreferences(this);
		psf.setMembersp();
		member = psf.getMembersp();
		try {
			if (getIntent().getStringExtra("stu_code") != null) {
				stu = Integer.parseInt(getIntent().getStringExtra("stu_code"));
			}
		} catch (Exception e) {
			stu = 0;
		}
		mHandler = new Handler();
		toolbar = (Toolbar) findViewById(R.id.MAIN_SLIDE_BEACON_TOOLBAR);
		state = (TextView) findViewById(R.id.MAIN_SLIDE_CHILDREN_STATE);
		start = (TextView) findViewById(R.id.MAIN_SLIDE_CHILDREN_START);
		
		if(android.os.Build.VERSION.SDK_INT>=android.os.Build.VERSION_CODES.KITKAT){
			start.setVisibility(View.VISIBLE);
			
			mLeScanCallback = new BluetoothAdapter.LeScanCallback() {
			@Override
			public void onLeScan(final BluetoothDevice device, int rssi,
					byte[] scanRecord) {
				final int rss = rssi;
				final byte[] scan = scanRecord;
				runOnUiThread(new Runnable() {
					@Override
					public void run() {
						if (device.getAddress().equals(beacon)) {
							check = true;
							onNetworkCallback(SCANSUCCESS, "");
							scanLeDevice(false);
						}
					}
				});
			}
		};
		
		}else{
			start.setVisibility(View.GONE);
			Toast.makeText(this, "현재 기기의 버전은 지키미 서비스를 지원 하지 않습니다.", Toast.LENGTH_LONG).show();
		}
		 toolbar.setNavigationOnClickListener(new OnClickListener() {
		 
		 @Override public void onClick(View v) { finish(); } });

		startNetwork(1);
		startDIal();
	}

	@Override
	public void startThread(int choice) {
		// TODO Auto-generated method stub
		super.startThread(choice);
		final int cho = choice;
		firstThread = new Thread(new Runnable() {

			@Override
			public void run() {
				// TODO Auto-generated method stub
				switch (cho) {
				case 1:
					mainThread();
					break;
				case 2:
					upThread();
					break;
				}
			}
		});
		firstThread.start();
	}

	@Override
	protected void handlingMessage(Message _message) {
		// TODO Auto-generated method stub
		super.handlingMessage(_message);
		switch (_message.what) {
		case CATCH_EXCEPTION:
			if (firstThread != null) {
				firstThread.interrupt();
			}
			endDIal();
			sqlite_Connect.insert_Err_Log((String)_message.obj,android.os.Build.VERSION.SDK_INT,"Main_Slide_Beacon", member.Email);	
			break;
		case SUCCESS:
			if (firstThread != null) {
				firstThread.interrupt();
			}
			endDIal();
			String BeaId = "";
			
			try{
				BeaId = beacon.split(":")[3]+""+beacon.split(":")[4]+""+beacon.split(":")[5];
			}catch(Exception ex){
				BeaId = "비콘이 없습니다.";
			}
			state.setText(BeaId);
			start.setOnClickListener(new OnClickListener() {

				@Override
				public void onClick(View v) {
					// TODO Auto-generated method stub
					final BluetoothManager bluetoothManager = (BluetoothManager) getSystemService(Context.BLUETOOTH_SERVICE);
					mBluetoothAdapter = bluetoothManager.getAdapter();
					if (mBluetoothAdapter == null
							|| !mBluetoothAdapter.isEnabled()) {
						Intent enableBtIntent = new Intent(
								BluetoothAdapter.ACTION_REQUEST_ENABLE);
						startActivityForResult(enableBtIntent,
								REQUEST_ENABLE_BT);
					} else {
						startDIal();
						check = false;
						scanLeDevice(true);
					}
				}
			});
			break;
		case FAIR:
			if (firstThread != null) {
				firstThread.interrupt();
			}
			endDIal();
			Toast.makeText(this, _message.obj.toString(), Toast.LENGTH_SHORT)
					.show();
			break;
		case SCANSUCCESS:
			endDIal();
			state.setText("지키미 인식성공 정보체크중");
			registerReceiver(mGattUpdateReceiver, makeGattUpdateIntentFilter());
			final Intent gattServiceIntent = new Intent(this,
					BluetoothLeService.class);
			bindService(gattServiceIntent, mServiceConnection, BIND_AUTO_CREATE);

			break;

		case SCANFAIR:

			endDIal();
			state.setText("지키미 인식못함");
			break;
		case BATTERYUP:
			state.setText("정상");
			endDIal();
			break;
		}

	}

	public void mainThread() {
		try {
			JSONObject jsonObject = new JSONObject(publicHttpCallback(HTTP_URL,
					"code=" + MAIN_JIKIMI + "&stu=" + stu));
			if (jsonObject.getBoolean("success")) {
				beacon = jsonObject.getString("stu");
				onNetworkCallback(SUCCESS, "");
			} else {
				onNetworkCallback(FAIR, jsonObject.getString("message"));
			}
		} catch (Exception e) {
			onNetworkCallback(CATCH_EXCEPTION, e.toString()+" where mainThread()");
		}
	}

	public void upThread() {
		try {
			JSONObject jsonObject = new JSONObject(publicHttpCallback(HTTP_URL,
					"code=" + MAIN_UPBEACON + "&beacon=" + beacon + "&battery="
							+ battery));
			beacon = jsonObject.getString("stu");
			onNetworkCallback(BATTERYUP, "");
		} catch (Exception e) {
			onNetworkCallback(CATCH_EXCEPTION, e.toString()+" where upThread()");
		}
	}

	private void scanLeDevice(final boolean enable) {

		if (enable) {
			// Stops scanning after a pre-defined scan period.
			mHandler.postDelayed(new Runnable() {
				@Override
				public void run() {
					scanLeDevice(false);
					if (!check) {
						endDIal();
						onNetworkCallback(SCANFAIR, "");
					}
				}
			}, SCAN_PERIOD);
			mBluetoothAdapter.startLeScan(mLeScanCallback);
		} else {
			mBluetoothAdapter.stopLeScan(mLeScanCallback);
		}
	}

	private BluetoothAdapter.LeScanCallback mLeScanCallback/* = new BluetoothAdapter.LeScanCallback() {
		@Override
		public void onLeScan(final BluetoothDevice device, int rssi,
				byte[] scanRecord) {
			final int rss = rssi;
			final byte[] scan = scanRecord;
			runOnUiThread(new Runnable() {
				@Override
				public void run() {
					if (device.getAddress().equals(beacon)) {
						check = true;
						onNetworkCallback(SCANSUCCESS, "");
						scanLeDevice(false);
					}
				}
			});
		}
	}*/;

	private final ServiceConnection mServiceConnection = new ServiceConnection() {

		@Override
		public void onServiceConnected(ComponentName componentName,
				IBinder service) {
			mBluetoothLeService = ((BluetoothLeService.LocalBinder) service)
					.getService();
			if (!mBluetoothLeService.initialize()) {
				finish();
			}
			// Automatically connects to the device upon successful start-up
			// initialization.
			mBluetoothLeService.connect(beacon);

		}

		@Override
		public void onServiceDisconnected(ComponentName componentName) {
			mBluetoothLeService = null;
		}
	};

	private final BroadcastReceiver mGattUpdateReceiver = new BroadcastReceiver() {
		@Override
		public void onReceive(Context context, Intent intent) {
			final String action = intent.getAction();
			if (BluetoothLeService.ACTION_GATT_CONNECTED.equals(action)) {
			} else if (BluetoothLeService.ACTION_GATT_DISCONNECTED
					.equals(action)) {
				unregisterReceiver(mGattUpdateReceiver);
			} else if (BluetoothLeService.ACTION_GATT_SERVICES_DISCOVERED
					.equals(action)) {
				displayGattServices(mBluetoothLeService
						.getSupportedGattServices());

			} else if (BluetoothLeService.ACTION_DATA_AVAILABLE.equals(action)) {
				battery = null;
				battery = intent.getStringExtra(BluetoothLeService.EXTRA_DATA);
				battery = battery.charAt(2) + "" + battery.charAt(3);
				battery = getHexToDec(battery);
				unbindService(mServiceConnection);
				mBluetoothLeService.close();

				if (battery == null) {
					endDIal();
				} else {
					startNetwork(2);
				}
			}
		}
	};

	private void displayGattServices(List<BluetoothGattService> gattServices) {
		if (gattServices == null)
			return;
		String uuid = null;
		String unknownServiceString = "Unknown service";
		String unknownCharaString = "Unknown characteristic";
		ArrayList<HashMap<String, String>> gattServiceData = new ArrayList<HashMap<String, String>>();
		ArrayList<ArrayList<HashMap<String, String>>> gattCharacteristicData = new ArrayList<ArrayList<HashMap<String, String>>>();
		mGattCharacteristics = new ArrayList<ArrayList<BluetoothGattCharacteristic>>();

		// Loops through available GATT Services.
		int servicescheck = 0;
		int characteristicscheck = 0;
		int servicescount = 0;
		int characteristicscount = 0;
		for (BluetoothGattService gattService : gattServices) {

			HashMap<String, String> currentServiceData = new HashMap<String, String>();
			uuid = gattService.getUuid().toString();
			currentServiceData.put(LIST_NAME,
					SampleGattAttributes.lookup(uuid, unknownServiceString));
			currentServiceData.put(LIST_UUID, uuid);
			gattServiceData.add(currentServiceData);

			ArrayList<HashMap<String, String>> gattCharacteristicGroupData = new ArrayList<HashMap<String, String>>();
			List<BluetoothGattCharacteristic> gattCharacteristics = gattService
					.getCharacteristics();
			ArrayList<BluetoothGattCharacteristic> charas = new ArrayList<BluetoothGattCharacteristic>();

			// Loops through available Characteristics.
			characteristicscheck = 0;
			for (BluetoothGattCharacteristic gattCharacteristic : gattCharacteristics) {
				charas.add(gattCharacteristic);
				HashMap<String, String> currentCharaData = new HashMap<String, String>();
				uuid = gattCharacteristic.getUuid().toString();
				currentCharaData.put(LIST_NAME,
						SampleGattAttributes.lookup(uuid, unknownCharaString));
				currentCharaData.put(LIST_UUID, uuid);
				gattCharacteristicGroupData.add(currentCharaData);
				if (uuid.equals("00002a19-0000-1000-8000-00805f9b34fb")) {
					servicescount = servicescheck;
					characteristicscount = characteristicscheck;
				}
				characteristicscheck++;
			}
			mGattCharacteristics.add(charas);
			gattCharacteristicData.add(gattCharacteristicGroupData);
			servicescheck++;
		}

		if (mGattCharacteristics != null) {
			final BluetoothGattCharacteristic characteristic = mGattCharacteristics
					.get(servicescount).get(characteristicscount);
			final int charaProp = characteristic.getProperties();
			if ((charaProp | BluetoothGattCharacteristic.PROPERTY_READ) > 0) {
				// If there is an active notification on a characteristic, clear
				// it first so it doesn't update the data field on the user
				// interface.
				if (mNotifyCharacteristic != null) {
					mBluetoothLeService.setCharacteristicNotification(
							mNotifyCharacteristic, false);
					mNotifyCharacteristic = null;
				}
				mBluetoothLeService.readCharacteristic(characteristic);
			}
			if ((charaProp | BluetoothGattCharacteristic.PROPERTY_NOTIFY) > 0) {
				mNotifyCharacteristic = characteristic;
				mBluetoothLeService.setCharacteristicNotification(
						characteristic, true);
			}
		}

	}

	private static IntentFilter makeGattUpdateIntentFilter() {
		final IntentFilter intentFilter = new IntentFilter();
		intentFilter.addAction(BluetoothLeService.ACTION_GATT_CONNECTED);
		intentFilter.addAction(BluetoothLeService.ACTION_GATT_DISCONNECTED);
		intentFilter
				.addAction(BluetoothLeService.ACTION_GATT_SERVICES_DISCOVERED);
		intentFilter.addAction(BluetoothLeService.ACTION_DATA_AVAILABLE);
		return intentFilter;
	}

	/**
	 * Hex -> 10진수 변환
	 * 
	 * @param hex
	 * @return
	 */
	private String getHexToDec(String hex) {

		long v = Long.parseLong(hex, 16);
		return String.valueOf(v);

	}
}
